package org.andolphin.client.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class StringUtils {
    public static final String COMMA = ",";
    public static final String EMPTY = "";
    public static final String BLANK_SPACE = " ";
    public static final String HEX_DIGITS = "0123456789ABCDEF";
    public static final String EMAIL_PATTERN_STR = "^(.+)@(.+)$";
    private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_PATTERN_STR);

    public static boolean isEmpty(String text) {
        return text == null || text.trim().equals("");
    }

    public static boolean isEmpty(CharSequence text) {
        return text == null || text.toString().trim().equals("");
    }

    public static boolean isValidConfirmPwd(String confirmPwd, String pwd) {
        if (isEmpty(pwd)) {
            if (isEmpty(confirmPwd)) {
                return true;
            } else {
                return false;
            }
        } else {
            if (pwd.equals(confirmPwd)) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * 验证是否为正确的email
     * 
     * @param text 要验证的文字
     * @param allowEmpty 是否允许为空
     * @return BOOLEAN
     */
    public static boolean isEmail(String text, boolean allowEmpty) {
        if (allowEmpty && isEmpty(text)) {
            return true;
        } else if (!allowEmpty && isEmpty(text)) {
            return false;
        } else if (!allowEmpty && !isEmail(text)) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 验证是否为正确的email
     * 
     * @param text 要验证的文字
     * @return BOOLEAN
     */
    public static boolean isEmail(String text) {
        AssertHelper.notNull(text);
        Matcher m = EMAIL_PATTERN.matcher(text);
        if (!m.find()) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 把流转换成字符串
     * 
     * @param stream 输入流
     * @return 字符串
     * @throws IOException IO异常
     */
    public static String readStringFromStream(InputStream stream) throws IOException {
        InputStreamReader isReader = new InputStreamReader(stream, Charset.forName("utf-8"));
        BufferedReader br = new BufferedReader(isReader);
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line).append("\n");
        }
        return sb.toString();
    }

    /**
     * 递归的找到Exception中的消息
     * 
     * @param e 异常
     * @return 消息
     */
    public static String digMessage(Throwable e) {
        String msg = e.getMessage();
        if (msg == null && e.getCause() != null) {
            return digMessage(e.getCause());
        }
        return msg;
    }

    /**
     * Join an array of Strings together.
     * 
     * @param glue Token to place between Strings.
     * @param pieces Array of Strings to join.
     * @return String presentation of joined Strings.
     * @see #join(String,java.util.Iterator)
     */
    public static String join(List<String> pieces, String glue) {
        return join(pieces.iterator(), glue);
    }

    /**
     * Join an array of Strings together.
     * 
     * @param glue Token to place between Strings.
     * @param pieces Array of Strings to join.
     * @return String presentation of joined Strings.
     * @see #join(String,java.util.Iterator)
     */
    public static String join(Map<String, String> pieces, String glue) {
        List<String> tmp = new ArrayList<String>(pieces.size());
        for (Map.Entry<String, String> entry : pieces.entrySet()) {
            tmp.add(entry.getKey() + ":" + entry.getValue());
        }
        return join(tmp, glue);
    }

    /**
     * Join an Iteration of Strings together.
     * <p/>
     * <h5>Example</h5>
     * <p/>
     * <p/>
     * 
     * <pre>
     * // get Iterator of Strings (&quot;abc&quot;,&quot;def&quot;,&quot;123&quot;);
     * Iterator i = getIterator();
     * out.print(TextUtils.join(&quot;, &quot;, i));
     * // prints: &quot;abc, def, 123&quot;
     * </pre>
     * 
     * @param glue Token to place between Strings.
     * @param pieces Iteration of Strings to join.
     * @return String presentation of joined Strings.
     */
    private static String join(Iterator<String> pieces, String glue) {
        StringBuilder s = new StringBuilder();
        while (pieces.hasNext()) {
            s.append(pieces.next());

            if (pieces.hasNext()) {
                s.append(glue);
            }
        }
        return s.toString();
    }

    /**
     * 把十六进制的字符串转换为十进制字符串
     * 
     * @param hex 六进制的字符串
     * @return 十进制字符串
     */
    public static String hexToDec(String hex) {
        char[] sources = hex.toCharArray();
        int dec = 0;
        for (int i = 0; i < sources.length; i++) {
            int digit = HEX_DIGITS.indexOf(Character.toUpperCase(sources[i]));
            dec += digit * Math.pow(16, (sources.length - (i + 1)));
        }
        return String.valueOf(dec);
    }

    public static boolean isLong(String text) {
        try {
            new Long(text);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public static boolean isDouble(String text) {
        try {
            new Double(text);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public static String randomString(int length) {
        StringBuilder sb = new StringBuilder();
        Random rand = new Random();
        for (int i = 0; i < length; i++) {
            sb.append((char) (48 + rand.nextInt(122 - 48)));
        }
        return sb.toString();
    }

    public static String safe(String str) {
        return safe(str, "");
    }

    public static String safe(String str, String defaultValue) {
        return str == null ? defaultValue : str;
    }

    /**
     * 计算字符串中的某个字符的数量
     * 
     * @param text 要计算的字符串
     * @param c 字符
     * @return 数量,如果text为null,返回0
     */
    public static int count(String text, char c) {
        if (text == null) {
            return 0;
        }
        int result = 0;
        for (char it : text.toCharArray()) {
            if (it == c) {
                ++result;
            }
        }
        return result;
    }

    /**
     * 计算在字符串text中的第n个字符c的位置
     * 
     * @param text 要计算的字符串
     * @param c 字符
     * @param n 第几个
     * @return 如果没有找到c,返回-1,如果c的数量不够n返回-1
     */
    public static int charAt(String text, char c, int n) {
        int pos = -1;
        char[] charArray = text.toCharArray();
        int count = 0;
        for (int i = 0; i < charArray.length; i++) {
            if (charArray[i] == c) {
                ++count;
                if (count == n) {
                    pos = i;
                    break;
                }
            }
        }

        return pos;
    }

    /**
     * 用字符c把字符串src分割成字符串数组,如果字符c前面有逃逸符esc,不进行分割
     * 
     * @param src 字符串
     * @param c 分隔符
     * @param esc 逃逸符
     * @return 分割后的字符串数组
     */
    public static String[] splitWith(String src, char c, char esc) {
        if (src == null || src.trim().equals(EMPTY)) {
            return new String[0];
        }

        List<String> result = new ArrayList<String>();
        StringBuilder sb = new StringBuilder();
        char[] chars = src.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == c) {
                if (i > 0 && chars[i - 1] != esc) {
                    result.add(sb.toString());
                    sb = new StringBuilder();
                } else {
                    sb.deleteCharAt(sb.length() - 1);
                    sb.append(chars[i]);
                }
            } else if (i != 0 || chars[i] != c) {
                sb.append(chars[i]);
            }
        }
        if (!sb.toString().equals("")) {
            result.add(sb.toString());
        }

        return result.toArray(new String[result.size()]);
    }

    /**
     * 用字符c把字符串src分割成字符串数组,只分割第一个后面的不进行分割,如果字符c前面有逃逸符esc,不进行分割
     * 
     * @param src 字符串
     * @param c 分隔符
     * @param esc 逃逸符
     * @return 分割后的字符串数组
     */
    public static String[] splitFirstWith(String src, char c, char esc) {
        if (src == null || src.trim().equals("")) {
            return new String[0];
        }

        List<String> result = new ArrayList<String>();
        StringBuilder sb = new StringBuilder();
        char[] chars = src.toCharArray();
        boolean hit = false;
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == c && !hit) {
                if (i > 0 && chars[i - 1] != esc) {
                    result.add(sb.toString());
                    sb = new StringBuilder();
                    hit = true;
                } else {
                    sb.deleteCharAt(sb.length() - 1);
                    sb.append(chars[i]);
                }
            } else if (i != 0 || chars[i] != c) {
                sb.append(chars[i]);
            }
        }
        if (!sb.toString().equals("")) {
            result.add(sb.toString());
        }

        return result.toArray(new String[result.size()]);
    }

    /**
     * 根据空格来分割字符串
     * 
     * @param src 要分割的字符串
     * @return 分割结果
     */
    public static List<String> splitBySpace(String src) {
        src = src.replaceAll("\t", BLANK_SPACE);
        return asList(src, BLANK_SPACE);
    }

    /**
     * 根据separater把字符串分割成字符串数组
     * 
     * @param src 要分割的字符串
     * @param separater 分隔符
     * @return 分割结果
     */
    public static List<String> asList(String src, String separater) {
        List<String> result = new ArrayList<String>();
        if (src == null || src.trim().equals(EMPTY)) {
            return result;
        } else {
            String values[] = src.split(separater);
            for (String value : values) {
                if (!value.trim().equals(EMPTY)) {
                    result.add(value.trim());
                }
            }
            return result;
        }
    }

    /**
     * 把一个字符串按逗号分割, 并且去除两端空白
     * 
     * @param str 字符串
     * @return 分割后的列表
     */
    public static List<String> splitToList(String str) {
        StringTokenizer st = new StringTokenizer(str, COMMA);
        List<String> result = new ArrayList<String>();
        while (st.hasMoreTokens()) {
            String t = st.nextToken();
            if (!isEmpty(t)) {
                result.add(t.trim());
            }
        }
        return result;
    }

    /**
     * 把一个字符串按separater分割, 并且去除两端空白
     * 
     * @param str 字符串
     * @param separater 分割符
     * @return 分割后的列表
     */
    public static List<String> splitToList(String str, String separater) {
        StringTokenizer st = new StringTokenizer(str, separater);
        List<String> result = new ArrayList<String>();
        while (st.hasMoreTokens()) {
            String t = st.nextToken();
            if (!isEmpty(t)) {
                result.add(t.trim());
            }
        }
        return result;
    }

    /**
     * trim全角和半角空格
     * 
     * @param str 要trim的字符串
     * @return 两边去掉所有的全角和半角空格
     */
    public static String fullSpaceTrim(String str) {
        if (str == null) {
            return null;
        }
        int length = str.length();
        int start = 0;
        while ((start < length) && (str.charAt(start) == ' ' || str.charAt(start) == '\u3000')) {
            ++start;
        }
        int end = length - 1;
        while ((end >= 0) && (str.charAt(end) == ' ' || str.charAt(end) == '\u3000')) {
            --end;
        }
        return start > end ? "" : str.substring(start, end + 1);
    }

    /**
     * 解析字符串中的UTF-8字符, \\uxxxx;
     * 
     * @param src 源字符串
     * @return char
     */
    public static char decodeUTF8(String src) {
        if (src == null) {
            throw new IllegalArgumentException("Malformed \\uxxxx encoding.");
        }

        if (!(src.startsWith("\\u") && src.length() <= 6)) {
            throw new IllegalArgumentException("Malformed \\uxxxx encoding.");
        }

        char[] sources = src.substring(2).toCharArray();
        char res = 0;
        for (char nextChar : sources) {
            int digit = HEX_DIGITS.indexOf(Character.toUpperCase(nextChar));
            res = (char) (res * 16 + digit);
        }
        return res;
    }

    public static String decodeUTF8String(String src) {
        StringBuilder sb = new StringBuilder();
        char[] sources = src.toCharArray();
        for (int i = 0; i < sources.length; i++) {
            if (sources[i] == '\\' && i < sources.length - 5 && sources[i + 1] == 'u') {
                String utf8 = "" + sources[i++] + sources[i++] + sources[i++] + sources[i++] + sources[i++]
                        + sources[i];
                sb.append(decodeUTF8(utf8));
                i = i + 5;
            } else {
                sb.append(sources[i]);
            }
        }
        return sb.toString();
    }

    /**
     * 截取字符串
     * 
     * @param src 要截取的字符串
     * @param length 长度
     * @param end 结尾
     * @return 截取后的字符串
     */
    public static String truncate(String src, int length, String end) {
        if (src == null) {
            return null;
        }

        if (src.length() > length) {
            return src.substring(0, length) + end;
        } else {
            return src;
        }
    }

    /**
     * 取得字符串中的所有空格
     * 
     * @param src 字符串
     * @return 没有空格的字符串
     */
    public static String removeAllBlank(String src) {
        if (src == null) {
            return null;
        } else {
            return src.replaceAll("\\s+", "");
        }
    }

    public static boolean isNumber(String text) {
        if (isEmpty(text)) {
            return false;
        } else {
            try {
                new BigDecimal(text);
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    }
}
